package plugins;

import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.jar.JarFile;


/**
 *  
 *  Classe qui permet gerer tous les plugins (chargement et validation)
 *  
 * @author rita
 *
 */
public class PluginLoader {
	
	private String[] files;

	private ArrayList classPlugins;

	//private int index;


	/**
	 * constructeur par defaut
	 */
	public PluginLoader(){
		
		this.classPlugins = new ArrayList();
	}
	
	
	/**
	 * constructeur initial
	 * 
	 * @param files tableau de string contenant la liste de fichiers à charger
	 */
	public PluginLoader(String[] files){
		this();
		this.files = files;
		
		
	}
	
	
	public void setFiles(String[] files ){
		this.files = files;
	}

	
	
	/**
	 * Fonction de chargement de tous les plugins de type Plugins
	 * @return une collection de Plugins contenant les instances des plugins
	 * @throws Exception si file = null ou file.length = 0
	 */
	public Plugins[] loadAllStringPlugins() throws Exception {
		
		this.initializeLoader();

		Plugins[] tmpPlugins = new Plugins[this.classPlugins.size()];

		
		for(int index = 0 ; index < tmpPlugins.length; index++ ){
			
			tmpPlugins[index] = (Plugins)((Class)this.classPlugins.get(index)).newInstance();
		}
		
		return tmpPlugins;
		
	}


	
	/**
	 * methode qui permettra de charger les plugins, charger la classe personnage/equipements
	 * @throws Exception 
	 */
	private void initializeLoader() throws Exception {
		// TODO Auto-generated method stub
		//On vérifie que la liste des plugins à charger a été initialisé
		if(this.files == null || this.files.length == 0 ){
			throw new Exception("Pas de fichier spécifié");
		}
 

				File[] f = new File[this.files.length];

				System.out.println(f.toString());
				//Pour charger le .jar en memoire
				URLClassLoader loader;
				//Pour la comparaison de chaines
				String tmp = "";
				//Pour le contenu de l'archive jar
				Enumeration enumeration;
				//Pour déterminer quels sont les interfaces implementées
				Class tmpClass = null;

				for(int index = 0 ; index < f.length ; index ++ ){

					f[index] = new File(this.files[index]);
					//f[index] = new File("plugins/"+this.files[index]);

					if( !f[index].exists() ) {
						break;
					}

					URL u = f[index].toURL();
					//On creer un nouveau URLClassLoader pour charger le jar qui se trouve en dehors du CLASSPATH
					loader = new URLClassLoader(new URL[] {u}); 

					//On charge le jar en mémoire
					JarFile jar = new JarFile(f[index].getAbsolutePath());

					//On récupére le contenu du jar
					enumeration = jar.entries();


					while(enumeration.hasMoreElements()){

						tmp = enumeration.nextElement().toString();

						//On vérifie que le fichier courant est un .class (et pas un fichier d'informations du jar )
						if(tmp.length() > 6 && tmp.substring(tmp.length()-6).compareTo(".class") == 0) {

							tmp = tmp.substring(0,tmp.length()-6);
							tmp = tmp.replaceAll("/",".");

							tmpClass = Class.forName(tmp ,true,loader);

							for(int i = 0 ; i < tmpClass.getInterfaces().length; i ++ ){						
								this.classPlugins.add(tmpClass);					
							}

						}
					}// fin du while


				}//fin du for

		
		
		
		
		
	}
	
	
	
}
